package com.hifar.test.collectdata.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hifar.abi.utils.sys.SysUtils;
import com.hifar.fw.utils.bean.BusiRequest;
import com.hifar.fw.utils.lang.CollectionUtils;
import com.hifar.fw.utils.lang.NumberUtils;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.oldPlatform.utils.CommonUtil;
import com.hifar.oldPlatform.utils.SysCommonUtil;
import com.hifar.sys.DbUtils;
import com.hifar.test.collectdata.constant.CollectConsts;
import com.hifar.test.collectdata.mapper.CollectDataMapper;
import com.hifar.test.collectdata.pojo.CollectData;
import com.hifar.test.collectdata.pojo.VO.*;
import com.hifar.test.collectdata.service.ICollectDataService;
import com.hifar.test.equip.pojo.HfResEquip;
import com.hifar.test.equip.service.IHfResEquipService;
import com.hifar.utils.ToolKit;
import com.tssk.kylx.fw.utils.id.IdUtils;
import com.tssk.kylx.fw.utils.lang.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Pattern;

/**
 * <p>
 * 采集数据表 服务实现类
 * </p>
 *
 * @author wangkepeng
 * @since 2024-12-17 11:08:21
 */
@Service
public class CollectDataServiceImpl extends ServiceImpl<CollectDataMapper, CollectData> implements ICollectDataService {

    private final Pattern DB_PATTERN = Pattern.compile("jdbc:(.*)://[^/]+/(?<schemaName>[^\\?]*).*");

    @Autowired
    private IHfResEquipService resEquipService;
    @Autowired
    private DbUtils dbUtils;

    @Override
    public Page<ClimateCollectionData> pageData(Page<ClimateCollectionData> page, String equipCode, Date startTime, Date endTime) {
        List<String> existTableNameList = new ArrayList<>();

        String equipTableNamePrefix = StringUtils
                .trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));

        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);
        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new Page<>();
        }
        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);
        return baseMapper.pageData(page, existTableNameList, startDateTime, endDateTime);
    }

    @Override
    public List<ClimateCollectionData> listData(String equipCode, Date startTime, Date endTime) {
        List<String> existTableNameList = new ArrayList<>();
        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);
        String equipTableNamePrefix = StringUtils
                .trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));

        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new ArrayList<>();
        }
        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);

        String dbType = dbUtils.queryDbType();
        return baseMapper.listData(dbType, existTableNameList, startDateTime, endDateTime);
    }

    @Override
    public void batchAddClimateData(ClimateCollectDataBatchAddVO collectDataAddVO) {
        String equipId = collectDataAddVO.getEquipId();
        Date startTime = collectDataAddVO.getStartTime();
        Date endTime = collectDataAddVO.getEndTime();
        String testproperyPv = collectDataAddVO.getTestproperyPv();

        // 正负偏差值
        double deviation = NumberUtils.parseDouble(SysUtils.getSwithValueNoTenantId(new com.hifar.fw.utils.bean.BusiRequest(),
                "deviation"), 1);

        BigDecimal startHumidityPv = collectDataAddVO.getStartHumidityPv();
        BigDecimal endHumidityPv = collectDataAddVO.getEndHumidityPv();
        BigDecimal startTemperaturePv = collectDataAddVO.getStartTemperaturePv();
        BigDecimal endTemperaturePv = collectDataAddVO.getEndTemperaturePv();
        BigDecimal startPressurePv = collectDataAddVO.getStartPressurePv();
        BigDecimal endPressurePv = collectDataAddVO.getEndPressurePv();
        Long recordInterval = collectDataAddVO.getRecordInterval();

        Assert.isTrue(startTime.before(endTime), "结束时间不能小于开始时间!");
        // 差值 （秒）
        Long diffTime = (endTime.getTime() - startTime.getTime()) / 1000L;
        Long timeInterval = diffTime / recordInterval; // 时间间隔
        BigDecimal diffHumidityPv = BigDecimal.ZERO;
        if (Objects.nonNull(startHumidityPv) && Objects.nonNull(endHumidityPv)) {
            diffHumidityPv = endHumidityPv.subtract(startHumidityPv)
                    .divide(new BigDecimal(timeInterval), 1, RoundingMode.HALF_UP);
        }
        BigDecimal diffTemperaturePv = BigDecimal.ZERO;
        if (Objects.nonNull(startTemperaturePv) && Objects.nonNull(endTemperaturePv)) {
            diffTemperaturePv = endTemperaturePv.subtract(startTemperaturePv)
                    .divide(new BigDecimal(timeInterval), 1, RoundingMode.HALF_UP);
        }
        BigDecimal diffPressurePv = BigDecimal.ZERO;
        if (Objects.nonNull(startPressurePv) && Objects.nonNull(endPressurePv)) {
            diffPressurePv = endPressurePv.subtract(startPressurePv)
                    .divide(new BigDecimal(timeInterval), 1, RoundingMode.HALF_UP);
        }


        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        final int batchInsertSize = 1000;
        Date tempDate = startTime;
        String year = DateUtils.formatTime(tempDate, "yyyy");
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));

        String preTableName = String.format("%s%s_%s", equipTableNamePrefix, equipCode, year);

        boolean exist = dbUtils.tableIsExist(preTableName);
        String dbType = dbUtils.queryDbType();
        if (!exist) {
            dbUtils.createTableName(preTableName);
        }

        List<CollectData> insertData = new ArrayList<>(batchInsertSize);

        BigDecimal tempHumidityPv = startHumidityPv;
        BigDecimal tempTemperaturePv = startTemperaturePv;
        BigDecimal tempPressurePv = startPressurePv;

        while (tempDate.before(endTime)) {
            String tableName = String.format("%s%s_%s", equipTableNamePrefix, equipCode, year);
            exist = dbUtils.tableIsExist(preTableName);
            if (!Objects.equals(preTableName, tableName) && !exist) {
                dbUtils.createTableName(preTableName);
            }
            if (!Objects.equals(preTableName, tableName) && !insertData.isEmpty()) {
                baseMapper.batchInsertData(preTableName, insertData);
                insertData = new ArrayList<>(batchInsertSize);
            }
            if (insertData.size() >= batchInsertSize) {
                baseMapper.batchInsertData(preTableName, insertData);
                insertData = new ArrayList<>(batchInsertSize);
            }
            if (Objects.nonNull(tempHumidityPv)) {
                BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(1, RoundingMode.HALF_UP);
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.HUMIDITY_PV);
                collectData.setTagvalue(StringUtils.trimNull(tempHumidityPv.add(deviationBD)));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
                tempHumidityPv = tempHumidityPv.add(diffHumidityPv);
            }
            if (Objects.nonNull(tempTemperaturePv)) {
                BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(1, RoundingMode.HALF_UP);
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.TEMPERATURE_PV);
                collectData.setTagvalue(StringUtils.trimNull(tempTemperaturePv.add(deviationBD)));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
                tempTemperaturePv = tempTemperaturePv.add(diffTemperaturePv);
            }
            if (Objects.nonNull(tempPressurePv)) {
                BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(1, RoundingMode.HALF_UP);
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.PRESSURE_PV);
                collectData.setTagvalue(StringUtils.trimNull(tempPressurePv.add(deviationBD)));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
                tempPressurePv = tempPressurePv.add(diffPressurePv);
            }
            if (Objects.nonNull(testproperyPv)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.TESTPROPERY_PV);
                collectData.setTagvalue(testproperyPv);
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
            }

            preTableName = tableName;
            tempDate = new Date(tempDate.getTime() + recordInterval * 1000L);
        }
        if (!insertData.isEmpty() && exist) {
            baseMapper.batchInsertData(preTableName, insertData);
        }
    }

    @Override
    public void batchAddDynamicsData(DynamicsCollectDataBatchAddVO collectDataAddVO) {
        String equipId = collectDataAddVO.getEquipId();
        Date startTime = collectDataAddVO.getStartTime();
        Date endTime = collectDataAddVO.getEndTime();
        String direction = collectDataAddVO.getDirectionPv();
        BigDecimal vibrateValue = collectDataAddVO.getVibrateValuePv();
        BigDecimal duration = collectDataAddVO.getDurationPv();
        String vibarateStatus = collectDataAddVO.getVibarateStatusPv();
        Long recordInterval = collectDataAddVO.getRecordInterval();

        Assert.isTrue(startTime.before(endTime), "结束时间不能小于开始时间!");
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        final int batchInsertSize = 1000;
        Date tempDate = startTime;
        String year = DateUtils.formatTime(tempDate, "yyyy");
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));
        String preTableName = String.format("%s%s_%s", equipTableNamePrefix, equipCode, year);

        boolean exist = dbUtils.tableIsExist(preTableName);
        String dbType = dbUtils.queryDbType();

        List<CollectData> insertData = new ArrayList<>(batchInsertSize);
        while (tempDate.before(endTime)) {
            String tableName = String.format("%s%s_%s", equipTableNamePrefix, equipCode, year);
            if (!Objects.equals(preTableName, tableName) && !insertData.isEmpty()) {
                baseMapper.batchInsertData(preTableName, insertData);
                insertData = new ArrayList<>(batchInsertSize);
            }
            if (insertData.size() >= batchInsertSize) {
                baseMapper.batchInsertData(preTableName, insertData);
                insertData = new ArrayList<>(batchInsertSize);
            }
            if (StringUtils.isNotBlank(direction)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VIARANTDIRECT_PV);
                collectData.setTagvalue(StringUtils.trimNull(direction));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            if (Objects.nonNull(duration)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VIARANTDURATION_PV);
                collectData.setTagvalue(StringUtils.trimNull(duration));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            if (StringUtils.isNotBlank(vibarateStatus)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VARIANTSTATUS_PV);
                collectData.setTagvalue(StringUtils.trimNull(vibarateStatus));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            if (Objects.nonNull(vibrateValue)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VIARANTVALUE_PV);
                collectData.setTagvalue(StringUtils.trimNull(vibrateValue));
                collectData.setTimestamp(tempDate);
                collectData.setTagtype(1);
                insertData.add(collectData);
            }

            preTableName = tableName;
            tempDate = new Date(tempDate.getTime() + recordInterval * 1000L);
        }
        if (!insertData.isEmpty() && exist) {
            baseMapper.batchInsertData(preTableName, insertData);
        }
    }

    @Override
    public Page<ClimateCollectDataVO> listPageClimate(Page<ClimateCollectDataVO> page, String equipId, Date startTime, Date endTime) {
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        List<String> existTableNameList = new ArrayList<>();
        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));

        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new Page<>();
        }
        String dbType = dbUtils.queryDbType();

        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);

        return baseMapper.pageClimateData(page, dbType, existTableNameList, startDateTime, endDateTime);
    }

    @Override
    public List<ClimateCollectDataVO> listClimate(String equipId, Date startTime, Date endTime) {
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        List<String> existTableNameList = new ArrayList<>();
        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));
        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new ArrayList<>();
        }
        String dbType = dbUtils.queryDbType();

        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);

        return baseMapper.listClimateData(dbType, existTableNameList, startDateTime, endDateTime);
    }

    @Override
    public Page<DynamicsCollectDataVO> listPageDynamics(Page<DynamicsCollectDataVO> page, String equipId, Date startTime, Date endTime) {
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        List<String> existTableNameList = new ArrayList<>();
        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));
        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new Page<>();
        }
        String dbType = dbUtils.queryDbType();

        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);

        return baseMapper.pageDynamicsData(page, dbType, existTableNameList, startDateTime, endDateTime);
    }

    @Override
    public List<DynamicsCollectDataVO> listDynamics(String equipId, Date startTime, Date endTime) {
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        List<String> existTableNameList = new ArrayList<>();
        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));
        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new ArrayList<>();
        }
        String dbType = dbUtils.queryDbType();

        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);

        return baseMapper.listDynamicsData(dbType, existTableNameList, startDateTime, endDateTime);
    }

    @Override
    public void editDynamics(DynamicsCollectDataVO dynamicsCollectDataVO) {
        String direction = dynamicsCollectDataVO.getDirectionPv();
        BigDecimal duration = dynamicsCollectDataVO.getDurationPv();
        BigDecimal vibrateValue = dynamicsCollectDataVO.getVibrateValuePv();
        Date runningTime = dynamicsCollectDataVO.getRunningTime();
        String vibarateStatus = dynamicsCollectDataVO.getVibarateStatusPv();
        String tableName = dynamicsCollectDataVO.getTableName();

        // 正负偏差值
        double deviation = NumberUtils.parseDouble(SysUtils.getSwithValueNoTenantId(new com.hifar.fw.utils.bean.BusiRequest(),
                "deviation"), 1);


        String ids = dynamicsCollectDataVO.getId();
        List<String> idList = CollectionUtils.valueOfList(ids);
        String directionId = baseMapper.queryTagId(tableName, CollectConsts.VIARANTDIRECT_PV, idList);
        String durationId = baseMapper.queryTagId(tableName, CollectConsts.VIARANTDURATION_PV, idList);
        String variantStatusId = baseMapper.queryTagId(tableName, CollectConsts.VARIANTSTATUS_PV, idList);
        String vibrantValueId = baseMapper.queryTagId(tableName, CollectConsts.VIARANTVALUE_PV, idList);

        String dbType = dbUtils.queryDbType();

        if (Objects.isNull(directionId)) {
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.VIARANTDIRECT_PV);
            collectData.setTagvalue(StringUtils.trimNull(direction));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);
            baseMapper.insertData(dbType, tableName, collectData);

        } else {
            baseMapper.editData(dbType, tableName, StringUtils.trimNull(direction), directionId);
        }

        if (Objects.isNull(durationId)) {
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.VIARANTDURATION_PV);
            collectData.setTagvalue(duration == null ? null : StringUtils.trimNull(duration));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);
            baseMapper.insertData(dbType, tableName, collectData);

        } else {
            if (duration == null) {
                baseMapper.deleteCollectData(dbType, tableName, Arrays.asList(durationId));
            } else {
                baseMapper.editData(dbType, tableName, StringUtils.trimNull(duration), durationId);
            }
        }

        if (Objects.isNull(variantStatusId)) {
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.VARIANTSTATUS_PV);
            collectData.setTagvalue(StringUtils.trimNull(vibarateStatus));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);
            baseMapper.insertData(dbType, tableName, collectData);

        } else {
            baseMapper.editData(dbType, tableName, StringUtils.trimNull(vibarateStatus), variantStatusId);
        }

        if (Objects.isNull(vibrantValueId)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(2, RoundingMode.HALF_UP);
            vibrateValue = (vibrateValue != null) ? vibrateValue.add(deviationBD) : vibrateValue;
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.VIARANTVALUE_PV);
            collectData.setTagvalue(vibrateValue == null ? null : StringUtils.trimNull(vibrateValue));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);

            if (StringUtils.isNotEmpty(vibrateValue)) {
                baseMapper.insertData(dbType, tableName, collectData);
            }

        } else {
            if (vibrateValue == null) {
                baseMapper.deleteCollectData(dbType, tableName, Arrays.asList(vibrantValueId));

            } else {
                baseMapper.editData(dbType, tableName, StringUtils.trimNull(vibrateValue), vibrantValueId);
            }
        }
    }

    @Override
    public void editClimate(ClimateCollectDataVO climateCollectDataVO) {
        BigDecimal humidityPv = climateCollectDataVO.getHumidityPv();
        BigDecimal temperaturePv = climateCollectDataVO.getTemperaturePv();
        BigDecimal pressurePv = climateCollectDataVO.getPressurePv();
        Date runningTime = climateCollectDataVO.getRunningTime();
        String testproperyPv = climateCollectDataVO.getTestproperyPv();
        String tableName = climateCollectDataVO.getTableName();

        // 正负偏差值
        double deviation = NumberUtils.parseDouble(SysUtils.getSwithValueNoTenantId(new com.hifar.fw.utils.bean.BusiRequest(),
                "deviation"), 1);

        String ids = climateCollectDataVO.getId();
        List<String> idList = CollectionUtils.valueOfList(ids);
        String dbType = dbUtils.queryDbType();
        String humidityPvId = baseMapper.queryTagIdAndDbType(dbType, tableName, CollectConsts.HUMIDITY_PV, idList);
        String temperaturePvId = baseMapper.queryTagIdAndDbType(dbType, tableName, CollectConsts.TEMPERATURE_PV, idList);
        String pressurePvId = baseMapper.queryTagIdAndDbType(dbType, tableName, CollectConsts.PRESSURE_PV, idList);
        String testproperyPvId = baseMapper.queryTagIdAndDbType(dbType, tableName, CollectConsts.TESTPROPERY_PV, idList);


        if (Objects.isNull(humidityPvId)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(2, RoundingMode.HALF_UP);
            humidityPv = (humidityPv != null) ? humidityPv.add(deviationBD) : humidityPv;
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.HUMIDITY_PV);
            collectData.setTagvalue(humidityPv == null ? null : StringUtils.trimNull(humidityPv));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);

            if (StringUtils.isNotEmpty(humidityPv)) {
                baseMapper.insertData(dbType, tableName, collectData);
            }

        } else {
            if (humidityPv == null) {
                baseMapper.deleteCollectData(dbType, tableName, Arrays.asList(humidityPvId));

            } else {
                baseMapper.editData(dbType, tableName, StringUtils.trimNull(humidityPv), humidityPvId);
            }
        }

        if (Objects.isNull(temperaturePvId)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(2, RoundingMode.HALF_UP);
            temperaturePv = (temperaturePv != null) ? temperaturePv.add(deviationBD) : temperaturePv;
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.TEMPERATURE_PV);
            collectData.setTagvalue(temperaturePv == null ? null : StringUtils.trimNull(temperaturePv));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);
            if (StringUtils.isNotEmpty(temperaturePv)) {
                baseMapper.insertData(dbType, tableName, collectData);
            }

        } else {
            if (temperaturePv == null) {
                baseMapper.deleteCollectData(dbType, tableName, Arrays.asList(temperaturePvId));

            } else {
                baseMapper.editData(dbType, tableName, StringUtils.trimNull(temperaturePv), temperaturePvId);
            }
        }

        if (Objects.isNull(pressurePvId)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(2, RoundingMode.HALF_UP);
            pressurePv = (pressurePv != null) ? pressurePv.add(deviationBD) : pressurePv;
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.PRESSURE_PV);
            collectData.setTagvalue(pressurePv == null ? null : StringUtils.trimNull(pressurePv));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);
            if (StringUtils.isNotEmpty(pressurePv)) {
                baseMapper.insertData(dbType, tableName, collectData);
            }

        } else {
            if (pressurePv == null) {
                baseMapper.deleteCollectData(dbType, tableName, Arrays.asList(pressurePvId));

            } else {
                baseMapper.editData(dbType, tableName, StringUtils.trimNull(pressurePv), pressurePvId);
            }
        }

        if (Objects.isNull(testproperyPvId)) {
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.TESTPROPERY_PV);
            collectData.setTagvalue(StringUtils.trimNull(testproperyPv));
            collectData.setTimestamp(runningTime);
            collectData.setTagtype(1);

            if (StringUtils.isNotEmpty(testproperyPv)) {
                baseMapper.insertData(dbType, tableName, collectData);
            }

        } else {
            baseMapper.editData(dbType, tableName, StringUtils.trimNull(testproperyPv), testproperyPvId);
        }
    }

    @Override
    public void delete(CollectDataDeleteVO collectDataDeleteVO) {
        List<String> idList = new ArrayList<>();
        List<String> ids = collectDataDeleteVO.getId();
        for (String idStr : ids) {
            List<String> stringList = CollectionUtils.valueOfList(idStr);
            idList.addAll(stringList);
        }
        String tableName = collectDataDeleteVO.getTableName();

        boolean exist = dbUtils.tableIsExist(tableName);
        String dbType = dbUtils.queryDbType();
        if (!idList.isEmpty() && exist) {
            baseMapper.deleteCollectData(dbType, tableName, idList);
        }
    }

    @Override
    public void addClimateData(ClimateCollectDataAddVO collectDataAddVO) {
        String equipId = collectDataAddVO.getEquipId();
        String testproperyPv = collectDataAddVO.getTestproperyPv();
        BigDecimal humidityPv = collectDataAddVO.getHumidityPv();
        BigDecimal temperaturePv = collectDataAddVO.getTemperaturePv();
        BigDecimal pressurePv = collectDataAddVO.getPressurePv();
        Date recordTime = collectDataAddVO.getRecordTime();
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil
                .getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));
        String year = DateUtils.formatTime(recordTime, "yyyy");
        String tableName = String.format("%s%s_%s", equipTableNamePrefix, equipCode, year);

        // 正负偏差值
        double deviation = NumberUtils.parseDouble(SysUtils.getSwithValueNoTenantId(new com.hifar.fw.utils.bean.BusiRequest(),
                "deviation"), 1);

        boolean exist = dbUtils.tableIsExist(tableName);
        if (!exist) {
            dbUtils.createTableName(tableName);
        }

        List<CollectData> insertData = new ArrayList<>(4);
        if (Objects.nonNull(humidityPv)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(1, RoundingMode.HALF_UP);
            humidityPv = humidityPv.add(deviationBD);
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.HUMIDITY_PV);
            collectData.setTagvalue(StringUtils.trimNull(humidityPv));
            collectData.setTimestamp(recordTime);
            collectData.setTagtype(1);
            insertData.add(collectData);
        }
        if (Objects.nonNull(temperaturePv)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(1, RoundingMode.HALF_UP);
            temperaturePv = temperaturePv.add(deviationBD);
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.TEMPERATURE_PV);
            collectData.setTagvalue(StringUtils.trimNull(temperaturePv));
            collectData.setTimestamp(recordTime);
            collectData.setTagtype(1);
            insertData.add(collectData);
        }
        if (Objects.nonNull(pressurePv)) {
            BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(1, RoundingMode.HALF_UP);
            pressurePv = pressurePv.add(deviationBD);
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.PRESSURE_PV);
            collectData.setTagvalue(StringUtils.trimNull(pressurePv));
            collectData.setTimestamp(recordTime);
            collectData.setTagtype(1);
            insertData.add(collectData);
        }
        if (Objects.nonNull(testproperyPv)) {
            CollectData collectData = new CollectData();
            collectData.setTagid(IdUtils.uuid32());
            collectData.setTagname(CollectConsts.TESTPROPERY_PV);
            collectData.setTagvalue(testproperyPv);
            collectData.setTimestamp(recordTime);
            collectData.setTagtype(1);
            insertData.add(collectData);
        }
        if (!insertData.isEmpty()) {
            baseMapper.batchInsertData(tableName, insertData);
        }
    }

    @Override
    public void addDynamicsData(DynamicsCollectDataAddVO dynamicsCollectDataAddVO) {
        String equipId = dynamicsCollectDataAddVO.getEquipId();
        String direction = dynamicsCollectDataAddVO.getDirectionPv();
        long recordInterval = dynamicsCollectDataAddVO.getRecordInterval();
        BigDecimal vibrateValue = dynamicsCollectDataAddVO.getVibrateValuePv();
        BigDecimal duration = dynamicsCollectDataAddVO.getDurationPv();
        String vibarateStatus = dynamicsCollectDataAddVO.getVibarateStatusPv();
        Date startTime = dynamicsCollectDataAddVO.getStartTime();
        Date endTime = dynamicsCollectDataAddVO.getEndTime();
        HfResEquip hfResEquip = resEquipService.getById(equipId);
        Assert.notNull(hfResEquip, "设备数据不存在!");
        String equipCode = hfResEquip.getEquipCode();
        String year = DateUtils.formatTime(startTime, "yyyy");

        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil
                .getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));

        String tableName = String.format("%s%s_%s", equipTableNamePrefix, equipCode, year);

        // 正负偏差值
        double deviation = NumberUtils.parseDouble(SysUtils.getSwithValueNoTenantId(new com.hifar.fw.utils.bean.BusiRequest(),
                "deviation"), 1);

        boolean exist = dbUtils.tableIsExist(tableName);
        String dbType = dbUtils.queryDbType();

        List<CollectData> insertData = new ArrayList<>(4);
        long startTimeLong = startTime.getTime();
        long endTimeLong = endTime.getTime();

        long time = startTimeLong;
        while (endTimeLong >= time) {
            if (StringUtils.isNotBlank(direction)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VIARANTDIRECT_PV);
                collectData.setTagvalue(StringUtils.trimNull(direction));
                collectData.setTimestamp(new Date(time));
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            if (Objects.nonNull(duration)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VIARANTDURATION_PV);
                collectData.setTagvalue(StringUtils.trimNull(duration));
                collectData.setTimestamp(new Date(time));
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            if (StringUtils.isNotBlank(vibarateStatus)) {
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VARIANTSTATUS_PV);
                collectData.setTagvalue(StringUtils.trimNull(vibarateStatus));
                collectData.setTimestamp(new Date(time));
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            if (Objects.nonNull(vibrateValue)) {
                BigDecimal deviationBD = new BigDecimal(Math.random() * deviation).setScale(2, RoundingMode.HALF_UP);
                vibrateValue = (vibrateValue != null) ? vibrateValue.add(deviationBD) : vibrateValue;
                CollectData collectData = new CollectData();
                collectData.setTagid(IdUtils.uuid32());
                collectData.setTagname(CollectConsts.VIARANTVALUE_PV);
                collectData.setTagvalue(StringUtils.trimNull(vibrateValue));
                collectData.setTimestamp(new Date(time));
                collectData.setTagtype(1);
                insertData.add(collectData);
            }
            time += recordInterval;
        }
        if (!insertData.isEmpty() && exist) {
            baseMapper.batchInsertData(tableName, insertData);
        }
    }

    @Override
    public List<EquipRunRecordTimeVO> listRunRecord(String equipCode, Date startTime, Date endTime) {
        List<String> existTableNameList = new ArrayList<>();
        Integer startYear = DateUtils.getTime4Int(startTime);
        Integer endYear = DateUtils.getTime4Int(endTime);

        String equipTableNamePrefix = StringUtils.trimNull(SysCommonUtil
                .getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));

        for (int tempYear = startYear; tempYear <= endYear; tempYear++) {
            String tableName = equipTableNamePrefix + equipCode + "_" + tempYear;
            boolean exist = dbUtils.tableIsExist(tableName);
            if (exist) {
                existTableNameList.add(tableName);
            }
        }
        if (existTableNameList.isEmpty()) {
            return new ArrayList<>();
        }

        String dbType = dbUtils.queryDbType();
        LocalDateTime startDateTime = ToolKit.convertToDate(startTime);
        LocalDateTime endDateTime = ToolKit.convertToDate(endTime);
        List<EquipRunStatusCollectDataVO> equipRunStatusCollectDataVOS = baseMapper
                .listRunRecordData(dbType, existTableNameList, startDateTime, endDateTime);
        if (equipRunStatusCollectDataVOS.isEmpty()) {
            return new ArrayList<>();
        }
        List<EquipRunRecordTimeVO> equipRunRecordTimeVOList = new ArrayList<>();
        // 取出第一条数据
        EquipRunStatusCollectDataVO firstEquipRunData = equipRunStatusCollectDataVOS.get(0);
        // 从第二条开始计算
        String beforeRunStatus = firstEquipRunData.getRunStatus();
        Date beforeRunningTime = firstEquipRunData.getRunningTime();
        Long runTimeMill = 0L; // 运行时间 毫秒值

        for (int i = 0; i < equipRunStatusCollectDataVOS.size(); i++) {
            EquipRunStatusCollectDataVO equipRunStatusCollectDataVO = equipRunStatusCollectDataVOS.get(i);
            String runStatus = equipRunStatusCollectDataVO.getRunStatus();
            Date runningTime = equipRunStatusCollectDataVO.getRunningTime();
            if (ToolKit.isValidDate(beforeRunningTime, runningTime)) {
                if (Objects.equals(beforeRunStatus, CollectConsts.EQUIP_RUN_STATUS) || Objects.equals(runStatus, CollectConsts.EQUIP_RUN_STATUS)) {
                    runTimeMill += (runningTime.getTime() - beforeRunningTime.getTime());
                }
            } else {
                EquipRunRecordTimeVO equipRunRecordTimeVO = new EquipRunRecordTimeVO();
                equipRunRecordTimeVO.setEquipCode(equipCode);
                equipRunRecordTimeVO.setRecordTime(beforeRunningTime);
                BigDecimal runTime = new BigDecimal(String.valueOf(runTimeMill))
                        .divide(new BigDecimal("3600000"), 2, RoundingMode.HALF_UP);
                equipRunRecordTimeVO.setRunTime(runTime);
                equipRunRecordTimeVOList.add(equipRunRecordTimeVO);
                runTimeMill = 0L;
            }
            beforeRunStatus = runStatus;
            beforeRunningTime = runningTime;
        }
        return equipRunRecordTimeVOList;
    }

    @Override
    public List<CollectData> queryClimateData(String equipCode, Date startTime, Date endTime) {
        String dbType = dbUtils.queryDbType();
        Integer currentYear = DateUtils.getTime4Int(startTime);
        String equipTableNamePrefix = StringUtils
                .trimNull(SysCommonUtil.getSysConfigValueByKey(new BusiRequest(), "equipTableNamePrefix"));
        String tableName = equipTableNamePrefix + equipCode + "_" + currentYear;
        LocalDateTime startDateTime = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime endDateTime = endTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        boolean exist = dbUtils.tableIsExist(tableName);
        if (exist) {
            return baseMapper.queryRunRecordData(dbType, tableName, startDateTime, endDateTime);

        } else {
            return new ArrayList<>();
        }
    }
}
